home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / ada / gnat-3.05- / gnat-3 / gnat-3.05-i486-linux-elf-bin / rts / g-os_lib.adb < prev    next >
Encoding:
Text File  |  1996-06-07  |  14.3 KB  |  495 lines

  1. ------------------------------------------------------------------------------
  2. --                                                                          --
  3. --                         GNAT COMPILER COMPONENTS                         --
  4. --                                                                          --
  5. --                          G N A T . O S _ L I B                           --
  6. --                                                                          --
  7. --                                 B o d y                                  --
  8. --                                                                          --
  9. --                            $Revision: 1.33 $                             --
  10. --                                                                          --
  11. --   Copyright (C) 1992,1993,1994,1995,1996 Free Software Foundation, Inc.  --
  12. --                                                                          --
  13. -- GNAT is free software;  you can  redistribute it  and/or modify it under --
  14. -- terms of the  GNU General Public License as published  by the Free Soft- --
  15. -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
  16. -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
  17. -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  18. -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
  19. -- for  more details.  You should have  received  a copy of the GNU General --
  20. -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
  21. -- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
  22. -- MA 02111-1307, USA.                                                      --
  23. --                                                                          --
  24. -- As a special exception,  if other files  instantiate  generics from this --
  25. -- unit, or you link  this unit with other files  to produce an executable, --
  26. -- this  unit  does not  by itself cause  the resulting  executable  to  be --
  27. -- covered  by the  GNU  General  Public  License.  This exception does not --
  28. -- however invalidate  any other reasons why  the executable file  might be --
  29. -- covered by the  GNU Public License.                                      --
  30. --                                                                          --
  31. -- GNAT was originally developed  by the GNAT team at  New York University. --
  32. -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
  33. --                                                                          --
  34. ------------------------------------------------------------------------------
  35.  
  36. with Unchecked_Conversion;
  37. with System;                  use System;
  38. with System.Storage_Elements; use System.Storage_Elements;
  39.  
  40. package body GNAT.OS_Lib is
  41.  
  42.    -----------------------
  43.    -- Local Subprograms --
  44.    -----------------------
  45.  
  46.    function C_String_Length (S : Address) return Integer;
  47.    --  Returns the length of a C string.  Does check for null address
  48.    --  (returns 0).
  49.  
  50.    procedure Spawn_Internal
  51.      (Program_Name : String;
  52.       Args         : Argument_List;
  53.       Success      : out Boolean;
  54.       Pid          : out Process_Id;
  55.       Blocking     : Boolean);
  56.    --  Internal routine to implement the to Spawn (blocking and non blocking)
  57.    --  routines. If Blocking is set to True then the spawn is blocking
  58.    --  otherwise it is non blocking. In this latter case the Pid contains
  59.    --  the process id number. The first three parameters are as in Spawn.
  60.  
  61.    ---------------------
  62.    -- C_String_Length --
  63.    ---------------------
  64.  
  65.    function C_String_Length (S : Address) return Integer is
  66.       function Strlen (S : Address) return Integer;
  67.       pragma Import (C, Strlen, "strlen");
  68.  
  69.    begin
  70.       if S = Null_Address then
  71.          return 0;
  72.       else
  73.          return Strlen (S);
  74.       end if;
  75.    end C_String_Length;
  76.  
  77.    ----------------------
  78.    -- Create_Temp_File --
  79.    ----------------------
  80.  
  81.    procedure Create_Temp_File
  82.      (FD   : out File_Descriptor;
  83.       Name : out Temp_File_Name)
  84.    is
  85.       function Get_Temp_Name (T : Address) return Address;
  86.       pragma Import (C, Get_Temp_Name, "mktemp");
  87.  
  88.    begin
  89.       Name := "GNAT-XXXXXX" & Ascii.NUL;
  90.  
  91.       --  Check for NULL pointer returned by C
  92.  
  93.       if Get_Temp_Name (Name'Address) = To_Address (0) then
  94.          FD := -1;
  95.       else
  96.          FD := Create_New_File (Name'Address, Binary);
  97.       end if;
  98.    end Create_Temp_File;
  99.  
  100.    -----------------
  101.    -- Delete_File --
  102.    -----------------
  103.  
  104.    procedure Delete_File (Name : Address; Success : out Boolean) is
  105.       R : Integer;
  106.  
  107.       function unlink (A : Address) return Integer;
  108.       pragma Import (C, unlink, "unlink");
  109.  
  110.    begin
  111.       R := unlink (Name);
  112.       Success := (R = 0);
  113.    end Delete_File;
  114.  
  115.    ----------------------
  116.    -- File_Time_Stamp  --
  117.    ----------------------
  118.  
  119.    function File_Time_Stamp (FD : File_Descriptor) return OS_Time is
  120.       function File_Time (FD    : File_Descriptor) return OS_Time;
  121.       pragma Import (C, File_Time, "file_time_fd");
  122.  
  123.    begin
  124.       return File_Time (FD);
  125.    end File_Time_Stamp;
  126.  
  127.    ----------------------
  128.    -- File_Time_Stamp  --
  129.    ----------------------
  130.  
  131.    function File_Time_Stamp (Name : String) return OS_Time is
  132.  
  133.       function File_Time (Name : Address) return OS_Time;
  134.       pragma Import (C, File_Time, "file_time_name");
  135.  
  136.       F_Name : String (1 .. Name'Length + 1);
  137.  
  138.    begin
  139.       F_Name (1 .. Name'Length) := Name;
  140.       F_Name (Name'Length + 1)  := Ascii.NUL;
  141.       return File_Time (F_Name'Address);
  142.    end File_Time_Stamp;
  143.  
  144.    ------------
  145.    -- Getenv --
  146.    ------------
  147.  
  148.    function Getenv (Name : String) return String_Access is
  149.  
  150.       procedure Get_Env_Value_Ptr (Name, Length, Ptr : Address);
  151.       pragma Import (C, Get_Env_Value_Ptr, "get_env_value_ptr");
  152.  
  153.       procedure Strncpy (Astring_Addr, Cstring : Address; N : Integer);
  154.       pragma Import (C, Strncpy, "strncpy");
  155.  
  156.       Env_Value_Ptr    : Address;
  157.       Env_Value_Length : Integer;
  158.       F_Name           : String (1 .. Name'Length + 1);
  159.       Result           : String_Access;
  160.  
  161.    begin
  162.       F_Name (1 .. Name'Length) := Name;
  163.       F_Name (Name'Length + 1)  := Ascii.NUL;
  164.  
  165.       Get_Env_Value_Ptr
  166.         (F_Name'Address, Env_Value_Length'Address, Env_Value_Ptr'Address);
  167.  
  168.       Result := new String (1 .. Env_Value_Length);
  169.  
  170.       if Env_Value_Length > 0 then
  171.          Strncpy (Result.all'Address, Env_Value_Ptr, Env_Value_Length);
  172.       end if;
  173.  
  174.       return Result;
  175.    end Getenv;
  176.  
  177.    ------------
  178.    -- GM_Day --
  179.    ------------
  180.  
  181.    function GM_Day (Date : OS_Time) return Day_Type is
  182.       Y  : Year_Type;
  183.       Mo : Month_Type;
  184.       D  : Day_Type;
  185.       H  : Hour_Type;
  186.       Mn : Minute_Type;
  187.       S  : Second_Type;
  188.  
  189.    begin
  190.       GM_Split (Date, Y, Mo, D, H, Mn, S);
  191.       return D;
  192.    end GM_Day;
  193.  
  194.    -------------
  195.    -- GM_Hour --
  196.    -------------
  197.  
  198.    function GM_Hour (Date : OS_Time) return Hour_Type is
  199.       Y  : Year_Type;
  200.       Mo : Month_Type;
  201.       D  : Day_Type;
  202.       H  : Hour_Type;
  203.       Mn : Minute_Type;
  204.       S  : Second_Type;
  205.  
  206.    begin
  207.       GM_Split (Date, Y, Mo, D, H, Mn, S);
  208.       return H;
  209.    end GM_Hour;
  210.  
  211.    ---------------
  212.    -- GM_Minute --
  213.    ---------------
  214.  
  215.    function GM_Minute (Date : OS_Time) return Minute_Type is
  216.       Y  : Year_Type;
  217.       Mo : Month_Type;
  218.       D  : Day_Type;
  219.       H  : Hour_Type;
  220.       Mn : Minute_Type;
  221.       S  : Second_Type;
  222.  
  223.    begin
  224.       GM_Split (Date, Y, Mo, D, H, Mn, S);
  225.       return Mn;
  226.    end GM_Minute;
  227.  
  228.    --------------
  229.    -- GM_Month --
  230.    --------------
  231.  
  232.    function GM_Month (Date : OS_Time) return Month_Type is
  233.       Y  : Year_Type;
  234.       Mo : Month_Type;
  235.       D  : Day_Type;
  236.       H  : Hour_Type;
  237.       Mn : Minute_Type;
  238.       S  : Second_Type;
  239.  
  240.    begin
  241.       GM_Split (Date, Y, Mo, D, H, Mn, S);
  242.       return Mo;
  243.    end GM_Month;
  244.  
  245.    ---------------
  246.    -- GM_Second --
  247.    ---------------
  248.  
  249.    function GM_Second (Date : OS_Time) return Second_Type is
  250.       Y  : Year_Type;
  251.       Mo : Month_Type;
  252.       D  : Day_Type;
  253.       H  : Hour_Type;
  254.       Mn : Minute_Type;
  255.       S  : Second_Type;
  256.  
  257.    begin
  258.       GM_Split (Date, Y, Mo, D, H, Mn, S);
  259.       return S;
  260.    end GM_Second;
  261.  
  262.    --------------
  263.    -- GM_Split --
  264.    --------------
  265.  
  266.    procedure GM_Split
  267.      (Date   : OS_Time;
  268.       Year   : out Year_Type;
  269.       Month  : out Month_Type;
  270.       Day    : out Day_Type;
  271.       Hour   : out Hour_Type;
  272.       Minute : out Minute_Type;
  273.       Second : out Second_Type)
  274.    is
  275.       procedure To_GM_Time
  276.         (P_Time_T, P_Year, P_Month, P_Day, P_Hours, P_Mins, P_Secs : Address);
  277.       pragma Import (C, To_GM_Time, "to_gm_time");
  278.  
  279.       T  : OS_Time := Date;
  280.       Y  : Integer;
  281.       Mo : Integer;
  282.       D  : Integer;
  283.       H  : Integer;
  284.       Mn : Integer;
  285.       S  : Integer;
  286.  
  287.    begin
  288.       To_GM_Time (T'Address, Y'Address, Mo'Address, D'Address, H'Address,
  289.                   Mn'Address, S'Address);
  290.       Year   := Y + 1900;
  291.       Month  := Mo + 1;
  292.       Day    := D;
  293.       Hour   := H;
  294.       Minute := Mn;
  295.       Second := S;
  296.    end GM_Split;
  297.  
  298.    -------------
  299.    -- GM_Year --
  300.    -------------
  301.  
  302.    function GM_Year (Date : OS_Time) return Year_Type is
  303.       Y  : Year_Type;
  304.       Mo : Month_Type;
  305.       D  : Day_Type;
  306.       H  : Hour_Type;
  307.       Mn : Minute_Type;
  308.       S  : Second_Type;
  309.  
  310.    begin
  311.       GM_Split (Date, Y, Mo, D, H, Mn, S);
  312.       return Y;
  313.    end GM_Year;
  314.  
  315.    ------------------
  316.    -- Is_Directory --
  317.    ------------------
  318.  
  319.    function Is_Directory (Name : String) return Boolean is
  320.  
  321.       function Is_Directory (Name : Address) return Integer;
  322.       pragma Import (C, Is_Directory, "is_directory");
  323.  
  324.       F_Name : String (1 .. Name'Length + 1);
  325.  
  326.    begin
  327.       F_Name (1 .. Name'Length) := Name;
  328.       F_Name (Name'Length + 1)  := Ascii.NUL;
  329.       return Is_Directory (F_Name'Address) /= 0;
  330.    end Is_Directory;
  331.  
  332.    ---------------------
  333.    -- Is_Regular_File --
  334.    ---------------------
  335.  
  336.    function Is_Regular_File (Name : String) return Boolean is
  337.  
  338.       function Is_Regular_File (Name : Address) return Integer;
  339.       pragma Import (C, Is_Regular_File, "is_regular_file");
  340.  
  341.       F_Name : String (1 .. Name'Length + 1);
  342.  
  343.    begin
  344.       F_Name (1 .. Name'Length) := Name;
  345.       F_Name (Name'Length + 1)  := Ascii.NUL;
  346.       return Is_Regular_File (F_Name'Address) /= 0;
  347.    end Is_Regular_File;
  348.  
  349.    -------------------------
  350.    -- Locate_Regular_File --
  351.    -------------------------
  352.  
  353.    function Locate_Regular_File
  354.      (File_Name : String;
  355.       Path      : String)
  356.       return      String_Access
  357.    is
  358.       function Locate_Exec (Exec_Name, Path_Val : Address) return Address;
  359.       pragma Import (C, Locate_Exec, "locate_exec");
  360.  
  361.       --  "historical reasons" for the name of the C function. ???
  362.  
  363.       Exec_Name  : String (1 .. File_Name'Length + 1);
  364.       Path_Val   : String (1 .. Path'Length + 1);
  365.       Path_Addr  : Address;
  366.       Path_Len   : Integer;
  367.       Return_Val : String_Access;
  368.  
  369.    begin
  370.       Exec_Name (1 .. File_Name'Length) := File_Name;
  371.       Exec_Name (Exec_Name'Last)        := Ascii.NUL;
  372.       Path_Val  (1 .. Path'Length)      := Path;
  373.       Path_Val  (Path_Val'Last)         := Ascii.NUL;
  374.  
  375.       Path_Addr := Locate_Exec (Exec_Name'Address, Path_Val'Address);
  376.       Path_Len  := C_String_Length (Path_Addr);
  377.  
  378.       if Path_Len = 0 then
  379.          return null;
  380.       else
  381.          Return_Val := new String (1 .. Path_Len);
  382.  
  383.          declare
  384.             subtype Path_String is String (1 .. Path_Len);
  385.             type    Path_String_Access is access Path_String;
  386.             function Address_To_Access is new
  387.               Unchecked_Conversion (Source => Address,
  388.                                     Target => Path_String_Access);
  389.             Path_Access : Path_String_Access := Address_To_Access (Path_Addr);
  390.  
  391.          begin
  392.             for J in 1 .. Path_Len loop
  393.                Return_Val (J) := Path_Access (J);
  394.             end loop;
  395.  
  396.             return Return_Val;
  397.          end;
  398.       end if;
  399.    end Locate_Regular_File;
  400.  
  401.    ------------------------
  402.    -- Non_Blocking_Spawn --
  403.    ------------------------
  404.  
  405.    function Non_Blocking_Spawn
  406.      (Program_Name : String;
  407.       Args         : Argument_List)
  408.       return         Process_Id
  409.    is
  410.       Junk : Boolean;
  411.       Pid  : Process_Id;
  412.  
  413.    begin
  414.       Spawn_Internal (Program_Name, Args, Junk, Pid, Blocking => False);
  415.       return Pid;
  416.    end Non_Blocking_Spawn;
  417.  
  418.    -----------
  419.    -- Spawn --
  420.    -----------
  421.  
  422.    procedure Spawn
  423.      (Program_Name : String;
  424.       Args         : Argument_List;
  425.       Success      : out Boolean)
  426.    is
  427.       Junk : Process_Id;
  428.  
  429.    begin
  430.       Spawn_Internal (Program_Name, Args, Success, Junk, Blocking => True);
  431.    end Spawn;
  432.  
  433.    --------------------
  434.    -- Spawn_Internal --
  435.    --------------------
  436.  
  437.    procedure Spawn_Internal
  438.      (Program_Name : String;
  439.       Args         : Argument_List;
  440.       Success      : out Boolean;
  441.       Pid          : out Process_Id;
  442.       Blocking     : Boolean)
  443.    is
  444.       Arg_List : array (1 .. Args'Length + 2) of Address;
  445.  
  446.       Arg : String_Access;
  447.  
  448.       function Portable_Spawn (Args : Address) return Integer;
  449.       pragma Import (C, Portable_Spawn, "portable_spawn");
  450.  
  451.       function Portable_No_Block_Spawn (Args : Address) return Process_Id;
  452.       pragma Import (C, Portable_No_Block_Spawn, "portable_no_block_spawn");
  453.  
  454.    begin
  455.       Arg := new String (1 .. Program_Name'Length + 1);
  456.       Arg (1 .. Program_Name'Length) := Program_Name;
  457.       Arg (Arg'Last)                 := Ascii.NUL;
  458.       Arg_List (1)                   := Arg.all'Address;
  459.  
  460.       for J in 1 .. Args'Length loop
  461.          Arg := new String (1 .. Args (J + Args'First - 1)'Length + 1);
  462.          Arg (1 .. Arg'Last - 1) := Args (J + Args'First - 1).all;
  463.          Arg (Arg'Last) := Ascii.NUL;
  464.          Arg_List (J + 1) := Arg.all'Address;
  465.       end loop;
  466.  
  467.       Arg_List (Arg_List'Last) := Null_Address;
  468.  
  469.       if Blocking then
  470.          Pid     := Invalid_Pid;
  471.          Success := (Portable_Spawn (Arg_List'Address) = 0);
  472.       else
  473.          Pid     := Portable_No_Block_Spawn (Arg_List'Address);
  474.          Success := (Pid /= Invalid_Pid);
  475.       end if;
  476.  
  477.    end Spawn_Internal;
  478.  
  479.    ------------------
  480.    -- Wait_Process --
  481.    ------------------
  482.  
  483.    procedure Wait_Process (Pid : out Process_Id; Success : out Boolean) is
  484.       Status : Integer;
  485.  
  486.       function Portable_Wait (S : Address) return Process_Id;
  487.       pragma Import (C, Portable_Wait, "portable_wait");
  488.  
  489.    begin
  490.       Pid := Portable_Wait (Status'Address);
  491.       Success := (Status = 0);
  492.    end Wait_Process;
  493.  
  494. end GNAT.OS_Lib;
  495.